package com.zxf.basic.adapter

import android.annotation.SuppressLint
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import androidx.recyclerview.widget.AsyncListDiffer
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.RecyclerView

/**
 * @author Jack 2021-05-01 23:03
 */
abstract class BaseAdapter<T : Any> : RecyclerView.Adapter<BaseAdapter<T>.Holder>() {

    abstract fun layout(): Int

    var onClickListener: ((v: View, position: Int) ->Unit)? = null

    private val mData by lazy {
        AsyncListDiffer(this, object: DiffUtil.ItemCallback<T>() {
            override fun areItemsTheSame(oldItem: T, newItem: T): Boolean {
                return oldItem == newItem
            }

            @SuppressLint("DiffUtilEquals")
            override fun areContentsTheSame(oldItem: T, newItem: T): Boolean {
                return oldItem.hashCode() == newItem.hashCode()
            }
        })
    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): Holder {
        return LayoutInflater.from(parent.context)
            .inflate(layout(), parent, false)
            .let {
                Holder(it)
            }
    }

    override fun getItemCount(): Int {
        return mData.currentList.size
    }

    override fun onBindViewHolder(holder: Holder, position: Int) {
        holder.itemView.tag = position
    }

    fun updateData(data: List<T>) {
        mData.submitList(data)
    }

    /**
     * 通过传递payload，可以只进行局部刷新，而不用刷新整个item
     * 同时还可以通过不同的payload，控制不同的局部刷新操作
     */
    fun updateItem(position: Int, payload: String) {
        notifyItemChanged(position, payload)
    }

    fun getData(): MutableList<T> {
        return mData.currentList.toMutableList()
    }

    open inner class Holder(itemView: View) : RecyclerView.ViewHolder(itemView) {

        private val onClick = View.OnClickListener {
            onClickListener?.invoke(it, layoutPosition)
        }

        init {
            itemView.setOnClickListener(onClick)
        }

        fun <V : View> getView(id: Int): V {
            return itemView.findViewById(id)
        }

        fun setText(id: Int, text: String): Holder {
            getView<TextView>(id).text = text
            return this
        }

        fun setOnClick(id: Int): Holder {
            itemView.findViewById<View>(id).setOnClickListener(onClick)
            return this
        }

    }
}